This is a draft version of a MISRA C++ 202x rule proposed for public review.
MISRA Rule 8.1.1
Category: Required
Analysis Type: Decidable,Single Translation Unit
Rationale
If a lambda with implicit capture (having =
or &
in the capture list) attempts to capture a member variable of a
class, what is in fact captured is the this
pointer. This behaviour can be surprising, and may result in undefined behaviour if
the lambda is called after the object’s lifetime has ended. This issue cannot occur for a transient lambda [1].
Note: implicitly capturing this
using [=]
is deprecated from C++20.
Example
class A
{
int16_t val;
void f()
{
auto a1 = [=]() // Non-compliant - val is not captured, but
{ return val; }; // 'this' is implicitly captured
auto a2 = [&]() // Non-compliant - val is not captured, but
{ return val; }; // 'this' is implicitly captured
auto a3 = [this]() // Compliant - 'this' explicitly captured
{ return val; };
auto a4 = [self = *this]() // Compliant - current object captured by copy
{ return self.val; };
auto i = [&]() // Rule does not apply - transient lambda
{ return val; } ();
}
};
Glossary
[1] Transient lambda
A lambda is transient when:
- It is immediately invoked; or
- It is passed to a function that does not store it.
A function does not store a lambda when:
- The function is defined in the same translation unit as the lambda; and
- The lambda is only copied or moved when it is passed as an argument; and
- The function only calls the lambda and/or passes the lambda to another function that does not store it.
Copyright The MISRA Consortium Limited © 2023